package net.qiqb.core.optional.dao;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import net.qiqb.core.common.BeanConverter;
import net.qiqb.core.common.DiffClassifyCollection;
import net.qiqb.core.common.IdLooker;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class BatchPODiff<T, PO> {

    private BeanConverter<T, PO> converter;

    private IdLooker idLooker;

    private final List<PO> newPOList = new ArrayList<>();

    private final List<PO> oldPOList = new ArrayList<>();

    private final List<PO> additionalList = new ArrayList<>();

    private final List<PO> deletedList = new ArrayList<>();

    private final List<ModifyPO<PO>> modifyedList = new ArrayList<>();


    public BatchPODiff(List<T> newList, List<T> oldList, BeanConverter<T, PO> converter) {
        this(newList, oldList, converter, object -> {
            // 默认查找id
            final Field idField = ReflectUtil.getField(object.getClass(), "id");
            if (idField != null) {
                return ReflectUtil.getFieldValue(object, idField);
            }
            throw new RuntimeException("找不到id属性");
        });
    }


    /**
     * @param newList 新的批量数据集合
     * @param oldList 旧的批量数据集合
     */
    public BatchPODiff(List<T> newList, List<T> oldList, BeanConverter<T, PO> converter, IdLooker idLooker) {
        this.converter = converter;
        if (newList != null) {
            for (T t : newList) {
                newPOList.add(converter.convert(t));
            }
        }
        if (oldList != null) {
            for (T t : oldList) {
                oldPOList.add(converter.convert(t));
            }
        }
        this.idLooker = idLooker;
        init();
    }


    private void init() {
        if (newPOList.isEmpty() && oldPOList.isEmpty()) {
            return;
        }
        if (newPOList.isEmpty()) {
            // 全部删除
            deletedList.addAll(oldPOList);
            return;
        }
        if (oldPOList.isEmpty()) {
            // 全部新增
            additionalList.addAll(newPOList);
            return;
        }
        // 比较
        DiffClassifyCollection<PO> diffClassifyCollection = new DiffClassifyCollection<>(newPOList, oldPOList, po -> idLooker.lookId(po).toString());
        final Collection<PO> deleteCells = diffClassifyCollection.getDeletedFromRight();
        final Collection<PO> additionalCells = diffClassifyCollection.getAdditionalFromRight();
        // 新增
        if (CollUtil.isNotEmpty(additionalCells)) {
            additionalList.addAll(additionalCells);
        }
        // 删除
        if (CollUtil.isNotEmpty(deleteCells)) {
            deletedList.addAll(deleteCells);
        }
        // 更新
        final Map<PO, PO> modifiedFromLeft = diffClassifyCollection.getModifiedFromLeft();
        if (CollUtil.isNotEmpty(modifiedFromLeft)) {
            modifiedFromLeft.forEach((key, value) -> modifyedList.add(new ModifyPO<>(key, value)));
        }
    }


    private boolean isEntity() {
        return false;
    }

    public List<PO> getAdditionalPOs() {
        return additionalList;
    }

    public List<PO> getDeletedPOs() {
        return deletedList;
    }

    public List<ModifyPO<PO>> getModifiedPOs() {
        return modifyedList;
    }

    public static class ModifyPO<P> {

        private final P newPO;

        private final P oldPO;

        private ModifyPO(P newPO, P oldPO) {
            this.newPO = newPO;
            this.oldPO = oldPO;
        }

        public P getNewPO() {
            return newPO;
        }

        public P getOldPO() {
            return oldPO;
        }
    }
}
